package com.itheima.dubbo.mongodb.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.itheima.commons.pojo.UserLocation;
import com.itheima.commons.vo.UserLocationVo;
import com.itheima.dubbo.interfaces.UserLocationApi;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.GeoDistanceQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.GetQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;

@Service

public class UserLocationApiImpl implements UserLocationApi {

    @Autowired
    private ElasticsearchTemplate esTemplate;

    /**
     * 这个方法什么时候执行 ??
     * <bean id=  class=  initMethod= de... />
     * 当这个Bean被Spring容器创建完后就会执行
     */
    @PostConstruct
    public void initIndex() {
        //  创建索引
        if (!esTemplate.indexExists(UserLocation.class)) {
            if (esTemplate.createIndex(UserLocation.class)) {
                //  添加映射
                esTemplate.putMapping(UserLocation.class);
            }
        }
    }

    @Override
    public Boolean updateUserLocation(Long userId, Double longitude, Double latitude, String address) {
        UpdateQuery query = new UpdateQuery();
        query.setClazz(UserLocation.class);
        query.setId(userId.toString());
        HashMap<String, Object> map = new HashMap<>();
        map.put("location", new GeoPoint(latitude, longitude));
        map.put("address", address);
        UpdateRequest data = new UpdateRequest().doc(map);

        query.setUpdateRequest(data);
        UpdateResponse update = esTemplate.update(query);
        System.out.println("update:为" + update);
        return update.getResult().getOp() >=1;
    }

    @Override
    public void addUserLocation(UserLocationVo userLocation) {
         esTemplate.index(new IndexQueryBuilder().withObject(userLocation).build());
    }

    @Override
    public UserLocationVo queryByUserId(Long userId) {
        GetQuery getQuery = new GetQuery();
        getQuery.setId(userId.toString());
        UserLocation userLocation = esTemplate.queryForObject(getQuery, UserLocation.class);
        UserLocationVo locationVo = UserLocationVo.format(userLocation);
        return locationVo;
    }

    @Override
    public List<UserLocationVo> queryUserFromLocation(Double longitude, Double latitude, Double distance, Integer counts) {

        GeoDistanceQueryBuilder qu=new GeoDistanceQueryBuilder("location");
        qu.point(latitude, longitude);
        qu.distance(distance, DistanceUnit.MILES);
        NativeSearchQuery query =new NativeSearchQuery(qu);
        query.setPageable(PageRequest.of(0,counts));
        List<UserLocation> userLocations = esTemplate.queryForList(query, UserLocation.class);

        return UserLocationVo.formatToList(userLocations);
    }
}